package is.progetto1.aritmeticExpression.builder.impl;

import is.progetto1.aritmeticExpression.AddOp;
import is.progetto1.aritmeticExpression.Expression;
import is.progetto1.aritmeticExpression.IntegerNoSign;
import is.progetto1.aritmeticExpression.MulOp;
import is.progetto1.aritmeticExpression.Operator;
import is.progetto1.aritmeticExpression.Utility;
import is.progetto1.aritmeticExpression.Variable;
import is.progetto1.aritmeticExpression.builder.ExpressionBuilderIF;

public class ExpressionBuilder implements ExpressionBuilderIF {

	private Expression root;

	@Override
	public void buildOperand(String s) {
		Expression operand;
		if (s.matches(Utility.REGEX_VARIABLE))
			operand = new Variable(s);
		else if (s.matches(Utility.REGEX_NUMBER))
			operand = new IntegerNoSign(new Integer(s));
		else
			throw new IllegalArgumentException();
		if (root != null) {
			if (root.getLeft() == null)
				root.setLeft(operand);
			else if (root.getRight() == null)
				root.setRight(operand);
			else
				throw new IllegalStateException();
		} else {
			throw new IllegalStateException();
		}
	}

	@Override
	public void buildOperator() {
		if (root == null)
			root = new Operator() {
			};
		else {
			Operator current = new Operator() {
			};
			if (root.getLeft() == null)
				root.setLeft(current);
			else
				root.setRight(current);
			current.setParent(root);
			root = current;
		}
	}

	@Override
	public void fixOperator(String s) {
		if(root!=null){
		Operator current;
		if (s.equals("+")) {
			current = new AddOp(Expression.ADD_MODE);
		} else if (s.equals("-")) {
			current = new AddOp(Expression.SUB_MODE);
		} else if (s.equals("*")) {
			current = new MulOp(Expression.MUL_MODE);
		} else if (s.equals("/")) {
			current = new MulOp(Expression.DIV_MODE);
		} else {
			throw new IllegalArgumentException();
		}
		current.setLeft(root.getLeft());
		current.setRight(root.getRight());
		current.setParent(root.getParent());
		if (root.getParent() != null) {
			if (root.getParent().getLeft() == root)
				root.getParent().setLeft(current);
			else
				root.getParent().setRight(current);
		}
		root = current;
		}
	}

	@Override
	public void endsOperator() {
		if (root != null) {
			if (root.getParent() != null) {
				root = root.getParent();
			}
		}
	}

	@Override
	public Expression getResult() {
		return root;
	}

}
